home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
-
- olddrag.c
-
- This module handles drag and drop when the Drag Manager is not
- available.
-
- Copyright © 1994-1995, Northwestern University.
-
- ----------------------------------------------------------------------------*/
-
- #include <stdio.h>
-
- #include "glob.h"
- #include "olddrag.h"
- #include "subscribe.h"
- #include "listutil.h"
- #include "windutil.h"
-
-
-
- static Boolean gFirstCall; /* true if first click loop call after mouse down */
- static ListHandle gSubjectList; /* handle to subject list record if in extracting
- binaries manually dialog, else nil */
- static OSErr gErr; /* error code */
-
-
-
- /*----------------------------------------------------------------------------
- DrawDragLine
-
- Draw or erase a horizontal dividing line in a list.
-
- Entry: list = handle to the list.
- lineV = vertical coordinate in list of line to draw or erase.
- ----------------------------------------------------------------------------*/
-
- static void DrawDragLine (ListHandle list, short lineV)
- {
- GrafPtr port, listPort;
- PenState savePen;
- Rect clipRect;
- static RgnHandle savedClip = nil;
-
- listPort = (**list).port;
-
- GetPort(&port);
- GetPenState(&savePen);
- SetPort(listPort);
- if (savedClip == nil) savedClip = NewRgn();
- GetClip(savedClip);
-
- clipRect = (**list).rView;
- ClipRect(&clipRect);
- PenMode(patXor);
- PenPat(&qd.black);
- PenSize(3, 3);
- MoveTo((**list).rView.left, lineV);
- LineTo((**list).rView.right - 3, lineV);
-
- SetClip(savedClip);
- SetPenState(&savePen);
- SetPort(port);
- }
-
-
-
- /*----------------------------------------------------------------------------
- GetDestRow
-
- Get the destination row in a list given a mouse position. Also determine
- whether or not the list needs to be scrolled.
-
- Entry: list = handle to list record.
- mousePt = mouse position in local coordinates.
-
- Exit: *destRow = row number of cell following destination, or
- -10 if mouse to left or right of list.
- *lineV = vertical coordinate of dividing line at destination
- in local coordinates, or -10 if mouse to left or right of list.
- *scrollDelta = delta in cells that list must be scrolled
- (-1, 0, or +1).
- ----------------------------------------------------------------------------*/
-
- static void GetDestRow (ListHandle list, Point mousePt, short *destRow,
- short *lineV, short *scrollDelta)
- {
- Rect rView, visible, dataBounds;
- Point cellSize;
-
- rView = (**list).rView;
- visible = (**list).visible;
- dataBounds = (**list).dataBounds;
- cellSize = (**list).cellSize;
-
- /* Check to see if the mouse is to the left or right of the list. */
-
- if (mousePt.h < rView.left || mousePt.h > rView.right) {
- *destRow = -10;
- *lineV = -10;
- *scrollDelta = 0;
- return;
- }
-
- /* See if scrolling is necessary. */
-
- if (mousePt.v < rView.top && visible.top > dataBounds.top) {
- *scrollDelta = -1;
- } else if (mousePt.v > rView.bottom && visible.bottom < dataBounds.bottom) {
- *scrollDelta = +1;
- } else {
- *scrollDelta = 0;
- }
-
- /* Compute the destination row. */
-
- *destRow = (mousePt.v - rView.top + (cellSize.v >> 1)) / cellSize.v + visible.top;
- if (*destRow < visible.top) *destRow = visible.top;
- if (*destRow > visible.bottom) *destRow = visible.bottom;
- if (*destRow > dataBounds.bottom) *destRow = dataBounds.bottom;
-
- /* Compute the v coordinate of the dividing line. */
-
- *lineV = cellSize.v * (*destRow - visible.top) + rView.top - 1;
-
- /* Adjust destination row for scrolling. */
-
- *destRow += *scrollDelta;
- }
-
-
-
- /*----------------------------------------------------------------------------
- TrackListDrag
-
- Track dragging within a list.
-
- Entry: theList = handle to list record.
-
- Exit: *destinationRow = row number of cell following destination
- when mouse button released, or -1 if no destination.
- ----------------------------------------------------------------------------*/
-
- static void TrackListDrag (ListHandle theList, short *destinationRow)
- {
- Boolean lineDrawn = false;
- Point mousePt;
- short destRow, lineV, scrollDelta, prevLineV;
-
- while (StillDown()) {
-
- GetMouse(&mousePt);
- GetDestRow(theList, mousePt, &destRow, &lineV, &scrollDelta);
-
- /* Erase the old dividing line if necessary. */
-
- if (lineDrawn && (lineV != prevLineV || scrollDelta != 0)) {
- DrawDragLine(theList, prevLineV);
- lineDrawn = false;
- }
-
- /* Autoscroll if necessary. */
-
- if (scrollDelta != 0) MyLScroll(scrollDelta, theList);
-
- /* Draw the new dividing line if necessary. */
-
- if (!lineDrawn && destRow >= 0) {
- DrawDragLine(theList, lineV);
- prevLineV = lineV;
- lineDrawn = true;
- }
-
- }
-
- if (lineDrawn) {
- DrawDragLine(theList, lineV);
- *destinationRow = destRow;
- } else {
- *destinationRow = -1;
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- DragMoveGroups
-
- This function handles dragging of groups within a user group list.
-
- Entry: wind = pointer to user group list window.
- ----------------------------------------------------------------------------*/
-
- static void DragMoveGroups (WindowPtr wind)
- {
- TWindow **info;
- ListHandle theList;
- short destRow;
- Boolean changed;
-
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
-
- TrackListDrag(theList, &destRow);
-
- if (destRow >= 0) {
- MoveSelectedListCells(theList, destRow, &changed);
- if (changed) (**info).changed = true;
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- DragMoveSubjects
-
- This function handles dragging of subjects within a subject list in the
- extract binaries manually dialog.
-
- Entry: theList = handle to list record.
- ----------------------------------------------------------------------------*/
-
- static void DragMoveSubjects (ListHandle theList)
- {
- short destRow;
- Boolean changed;
-
- TrackListDrag(theList, &destRow);
-
- if (destRow >= 0) MoveSelectedListCells(theList, destRow, &changed);
- }
-
-
-
- /*----------------------------------------------------------------------------
- MouseIsOverUserGroupList
-
- Check to see if the mouse is over a user group list.
-
- Exit: function result = true if mouse is over a user group list.
- *thePt = current mouse position in global coords.
- if function result = true:
- *theWind = pointer to user group list window.
- *theInfo = handle to group list window info.
- *theList = handle to group list record.
- if function result = false:
- *theWind, *theInfo, *theList unchanged.
- ----------------------------------------------------------------------------*/
-
- static Boolean MouseIsOverUserGroupList (Point *thePt, WindowPtr *theWind,
- TWindow ***theInfo, ListHandle *theList)
- {
- WindowPtr wind;
- TWindow **info;
- ListHandle list;
- Rect rView;
- GrafPtr port;
- Point localPt;
-
- GetPort(&port);
- GetMouse(thePt);
- LocalToGlobal(thePt);
- FindWindow(*thePt, &wind);
- if (wind != nil) {
- info = (TWindow**)GetWRefCon(wind);
- if ((**info).kind == kGroup && (**info).groupKind == kUserGroup) {
- list = (**info).theList;
- rView = (**list).rView;
- localPt = *thePt;
- SetPort(wind);
- GlobalToLocal(&localPt);
- if (PtInRect(localPt, &rView)) {
- *theWind = wind;
- *theInfo = info;
- *theList = list;
- SetPort(port);
- return true;
- }
- }
- }
- SetPort(port);
- return false;
- }
-
-
-
- /*----------------------------------------------------------------------------
- DragSubscribeGroups
-
- This function handles dragging of groups from the full group list window
- or new groups list window to a user group list window.
-
- There are two stages to the drag:
-
- First, a gray region outline of the cells is dragged out of the starting
- window. The user drags this gray region around the screen until the mouse
- is over a user group list window. At this point the gray region disappears
- and the first stage ends.
-
- In the second stage, a bold dividing line is tracked at the location where
- the groups will be copied if the mouse button is released, with autoscrolling.
- If the user moves the mouse to some other user group list window, that
- new window becomes the target window.
-
- Entry: startWind = pointer to starting group list window.
- startPt = initial click location in starting window, in
- local coordinates.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- static OSErr DragSubscribeGroups (WindowPtr startWind, Point startPt)
- {
- WindowPtr curWind;
- TWindow **startInfo, **curInfo;
- ListHandle startList, prevList = nil, curList;
- RgnHandle grayRgn;
- Cell curCell;
- Rect cellRect;
- Point tempPt, prevPt, curPt;
- GrafPtr port;
- GrafPort fullPort;
- Boolean rgnDrawn = true, lineDrawn = false;
- short lineV, prevLineV, destRow, scrollDelta;
- OSErr err = noErr;
-
- GetPort(&port);
-
- startInfo = (TWindow**)GetWRefCon(startWind);
- startList = (**startInfo).theList;
-
- /* Start stage 1 - drag a gray region around. */
-
- /* Construct the gray region from the selected cells in the starting window. */
-
- grayRgn = NewRgn();
- OpenRgn();
- SetPt(&curCell,0,0);
- while (LGetSelect(true, &curCell, startList)) {
- LRect(&cellRect, curCell, startList);
- FrameRect(&cellRect);
- curCell.v++;
- }
- CloseRgn(grayRgn);
-
- /* Offset the gray region to the current mouse location. */
-
- GetMouse(&curPt);
- OffsetRgn(grayRgn, curPt.h - startPt.h, curPt.v - startPt.v);
-
- /* Convert the gray region and the current mouse loc to global coords. */
-
- SetPt(&tempPt, 0, 0);
- LocalToGlobal(&tempPt);
- OffsetRgn(grayRgn, tempPt.h, tempPt.v);
- LocalToGlobal(&curPt);
-
- /* Create a full screen GrafPort. */
-
- OpenPort(&fullPort);
- CopyRgn(GetGrayRgn(), fullPort.visRgn);
- fullPort.portRect = (**GetGrayRgn()).rgnBBox;
- PenPat(&qd.gray);
- PenMode(patXor);
-
- /* Draw the initial gray region. */
-
- FrameRgn(grayRgn);
- prevPt = curPt;
-
- /* Drag the gray region around until the mouse is over a user
- group list window or the mouse is released. */
-
- while (StillDown()) {
-
- /* Break out of the loop if the mouse is over a user group list. */
-
- if (MouseIsOverUserGroupList(&curPt, &curWind, &curInfo, &curList)) break;
-
- /* Erase the old gray region if necessary. */
-
- if (rgnDrawn && !EqualPt(curPt, prevPt)) {
- FrameRgn(grayRgn);
- rgnDrawn = false;
- }
-
- /* Draw the new gray region if necessary. */
-
- if (!rgnDrawn) {
- OffsetRgn(grayRgn, curPt.h - prevPt.h, curPt.v - prevPt.v);
- FrameRgn(grayRgn);
- prevPt = curPt;
- rgnDrawn = true;
- }
-
- }
-
- if (rgnDrawn) FrameRgn(grayRgn);
- DisposeRgn(grayRgn);
- ClosePort(&fullPort);
- SetPort(port);
- if (!StillDown()) return noErr;
-
- /* Start stage 2 - track the destination dividing line, switching target
- user group list windows as necessary. */
-
- SetPort(curWind);
-
- while (StillDown()) {
-
- /* If the mouse is in some other user group list window, make that window
- the target window. */
-
- prevList = curList;
- if (MouseIsOverUserGroupList(&curPt, &curWind, &curInfo, &curList)) SetPort(curWind);
- GlobalToLocal(&curPt);
-
- /* Get the destination row. */
-
- GetDestRow(curList, curPt, &destRow, &lineV, &scrollDelta);
-
- /* Erase the old dividing line if necessary. */
-
- if (lineDrawn && (curList != prevList || scrollDelta != 0 || lineV != prevLineV)) {
- DrawDragLine(prevList, prevLineV);
- lineDrawn = false;
- }
-
- /* Autoscroll if necessary. */
-
- if (scrollDelta != 0) MyLScroll(scrollDelta, curList);
-
- /* Draw the new dividing line if necessary. */
-
- if (!lineDrawn && destRow >= 0) {
- DrawDragLine(curList, lineV);
- prevLineV = lineV;
- lineDrawn = true;
- }
-
- }
-
- if (lineDrawn) {
- DrawDragLine(prevList, prevLineV);
- err = CopyOrMoveSelectedGroups(startWind, curWind, destRow, true);
- if (err != noErr) goto exit;
- }
-
- SetPort(port);
- return noErr;
-
- exit:
-
- SetPort(port);
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- OldListClickLoop
-
- The click loop routine for lists. It handles dragging
- groups between and within group list windows, and dragging subjects
- in the extract binaries manually dialog.
-
- Exit: function result = true if mouse button still down, false
- if mouse button released.
- ----------------------------------------------------------------------------*/
-
- Boolean OldListClickLoop (void)
- {
- static Point firstPt;
- WindowPtr wind;
- TWindow **info;
- ListHandle theList;
- Point thePt;
- Rect rect, cellRect;
- Cell cellClicked;
-
- if (gFirstCall) {
- gFirstCall = false;
- GetMouse(&firstPt);
- return true;
- }
-
- if (gSubjectList == nil) {
- wind = MyFrontWindow();
- if (wind == nil) return false;
- info = (TWindow**)GetWRefCon(wind);
- theList = (**info).theList;
- } else {
- theList = gSubjectList;
- }
-
- SetRect(&rect, firstPt.h - 3, firstPt.v - 3, firstPt.h + 3, firstPt.v + 3);
- cellClicked = LLastClick(theList);
- LRect(&cellRect, cellClicked, theList);
- SectRect(&rect, &cellRect, &rect);
- GetMouse(&thePt);
- if (PtInRect(thePt, &rect)) return true;
-
- gDidDrag = true;
- if (gSubjectList != nil) {
- DragMoveSubjects(theList);
- } else if ((**info).groupKind == kUserGroup) {
- DragMoveGroups(wind);
- } else {
- gErr = DragSubscribeGroups(wind, firstPt);
- }
- return false;
- }
-
-
-
- /*----------------------------------------------------------------------------
- OldBeginListClick
-
- This function must be called just before calling LClick.
-
- Entry: subjectList = handle to subject list if extracting
- binaries manually dialog, else nil.
-
- Exit: gFirstCall = true, to notify our click loop function that this
- is the first call after a mouse down.
- ----------------------------------------------------------------------------*/
-
- void OldBeginListClick (ListHandle subjectList)
- {
- gFirstCall = true;
- gSubjectList = subjectList;
- gErr = noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- OldEndListClick
-
- This function must be called just after calling LClick to get and
- check the error code.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr OldEndListClick (void)
- {
- return gErr;
- }
-